package com.dream.service.user.impl;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.dream.common.model.response.BaseListResponse;
import com.dream.common.model.response.BaseResponse;
import com.dream.common.model.response.ErrorCode;
import com.dream.common.model.response.ListModel;
import com.dream.common.toolkits.cache.RedisCache;
import com.dream.common.toolkits.json.JsonUtils;
import com.dream.service.general.api.GeneralServiceApi;
import com.dream.service.general.domain.request.ForgetPWDEamilRequest;
import com.dream.service.image.bean.ImgUpS3Response;
import com.dream.service.promotion.api.app.PromotionAppService;
import com.dream.service.promotion.domain.enums.GrantCouponEvent;
import com.dream.service.user.api.UserService;
import com.dream.service.user.bean.ForgetPwdEmailBean;
import com.dream.service.user.config.TokenConfig;
import com.dream.service.user.config.UserConfig;
import com.dream.service.user.dao.UserDao;
import com.dream.service.user.domain.entity.Token;
import com.dream.service.user.domain.entity.User;
import com.dream.service.user.domain.entity.UserAttr;
import com.dream.service.user.domain.model.UserModel;
import com.dream.service.user.domain.model.UserReturnInfoModel;
import com.dream.service.user.util.*;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by kangd on 2016/3/24.
 * 上传头像
 * 修改密码
 */
public class UserServiceImpl implements UserService{

    private static final Log logger = LogFactory.getLog(UserServiceImpl.class);

    //redis
    private  static RedisCache redisCache = RedisCache.getInstance("user_redis_address");

    private static final String ForogetPWDCacheKeyPrefix = "FPWD_";

    //DAO
    private UserDao userDao;


    public UserDao getUserDao() {
        return userDao;
    }

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }


    private GeneralServiceApi generalServiceApi;

    public GeneralServiceApi getGeneralServiceApi() {
        return generalServiceApi;
    }

    @Autowired
    public void setGeneralServiceApi(GeneralServiceApi generalServiceApi) {
        this.generalServiceApi = generalServiceApi;
    }

    @Autowired
    private PromotionAppService promotionAppService;

    public PromotionAppService getPromotionAppService() {
        return promotionAppService;
    }

    @Autowired
    public void setPromotionAppService(PromotionAppService promotionAppService) {
        this.promotionAppService = promotionAppService;
    }

    /**
     * 注册
     *
     * @param uuid
     * @param tel    电话
     * @param nickname 昵称
     * @param passwd   密码
     * @return pin uuid token email nickname
     */
    @Override
    public BaseResponse<User> signUp(String uuid, String tel, String nickname, String passwd,String source) throws Exception {
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(tel) || StringUtils.isEmpty(uuid)){
            BaseResponse<User> baseResponse= new BaseResponse<User>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<User> baseResponse= new BaseResponse<User>();
        String pin = PINworker.getPIN();
        /**
         * remark: uuid  pin  发点击流 OR 写数据库
         */

        UserModel userModel= new UserModel(pin, nickname, UserConfig.DEFAULT_ICON, tel, passwd,UserConfig.DEFAULT_LoginType);

        //验证邮箱是否已经注册过，第三方登录获取的邮箱也会放到这个字段中
        if(userDao.selectByEmail(tel,UserConfig.DEFAULT_LoginType) != null){
            baseResponse.packData(false, ErrorCode.USERSTATUS_REGISTERED.getCode() ,
                    ErrorCode.USERSTATUS_REGISTERED.getError_msg(), null, null);
        }else{
            userModel.setSource(source);
            userDao.addUser(userModel);

            //发送首单优惠码
            try{
                BaseResponse<Integer> response = promotionAppService.systemBindCoupon(pin, null, GrantCouponEvent.REGISTER,null);
                if(!response.isSuccess()){
                    logger.error("bindCouponError:"+pin+","+response.getError_msg());
                }
            }catch (Exception e){
                e.printStackTrace();
            }

            userModel = userDao.selectByPIN(pin);
            Token token = UserToken.generateToken(uuid, pin);
            User user =new User(uuid,token.getValue(),userModel);
            user.setInvite_code(UserInviteCode.convertToInviteCode(userModel.getUser_id()));
            user.setRoute(getPinRoute(pin));
            user.setTokenTtl(UserToken.tokenTtl(pin));
            baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, user);

            /**RegisterSuccessEmailRequest registerSuccessEmailRequest = new RegisterSuccessEmailRequest(user.getLogin_email(),
                    UserConfig.userRegisterEmailFrom, UserConfig.userRegisterEmailSubject,
                    UserConfig.userRegisterEmailTitle, UserConfig.userRegisterLoggingInUrl,UserConfig.userRegisterShoppingNowUrl,
                    user.getNickname(),user.getPin());
            generalServiceApi.sendEmailRegisterSuccess(registerSuccessEmailRequest);**/
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    /**
     * 注册用户登陆
     * @param uuid
     * @param email  注册邮箱
     * @param passwd 密码  不需要了，默认为空
     * @return pin uuid token email nickname
     */
    @Override
    public BaseResponse<User> login(String uuid, String email, String passwd) {
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(email)){
            BaseResponse<User> baseResponse= new BaseResponse<User>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<User> baseResponse= new BaseResponse<User>();
        UserModel userModel;
        try {
            userModel=userDao.selectCheckPW(email,null,passwd,UserConfig.DEFAULT_LoginType);
            if(userModel == null){
                baseResponse.packData(true, ErrorCode.USERSTATUS_REGISTERED.getCode(),
                        ErrorCode.USERSTATUS_REGISTERED.getError_msg(), null, null);
            }else{
                /**
                 * remark: uuid  pin  发点击流 OR 写数据库
                 */
                Token token = UserToken.generateToken(uuid,userModel.getPin());
                User user =new User(uuid,token == null?"":token.getValue(),userModel);
                user.setInvite_code(UserInviteCode.convertToInviteCode(userModel.getUser_id()));
                user.setRoute(getPinRoute(userModel.getPin()));
                user.setTokenTtl(UserToken.tokenTtl(userModel.getPin()));
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }


    /**
     * 第三方登录
     *
     * @param uuid
     * @param loginType
     * @param returnInfo
     * @return pin uuid token email nickname
     */
    @Override
    public BaseResponse<User> trdPtyLogin(String uuid, Integer loginType, String returnInfo,String source) throws Exception {
        long startTime = System.currentTimeMillis();
        logger.debug("trdPtyLogin_log");
        if(loginType == null|| StringUtils.isEmpty(uuid) || StringUtils.isEmpty(returnInfo)
                || !UserConfig.THIRD_PARTY_LOGING_TYPE.contains(loginType)){
            BaseResponse<User> baseResponse= new BaseResponse<User>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        logger.debug("trdPtyLogin_log 1 - UserReturnInfoModel start: " + String.valueOf(System.currentTimeMillis() - startTime));
        UserReturnInfoModel userReturnInfoModel = JsonUtils.fromJson(returnInfo, new TypeToken<UserReturnInfoModel>() {
        }.getType());
        logger.debug("trdPtyLogin_log 1 - UserReturnInfoModel end: " + String.valueOf(System.currentTimeMillis() - startTime));
        if(userReturnInfoModel == null || userReturnInfoModel.getType() != loginType || StringUtils.isEmpty(userReturnInfoModel.getEmail())){
            logger.error("returnInfo:"+returnInfo);
            BaseResponse<User> baseResponse= new BaseResponse<User>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<User> baseResponse= new BaseResponse<User>();
        /**
         * remark: uuid  pin  发点击流 OR 写数据库
         */
//        现在第三方登录头像图片逻辑，理论上是应该显示第三方的图片，现在是第一次登录时，把他的头像图片下载下来，保存在本地
//        然后他下次登录时无论他返回的信息中头像有没有变化都不做处理，还是用本地保存的头像
// 因为再次修改用户信息时头像不做处理，所以头像设置为null
        logger.debug("trdPtyLogin_log 2 - first DB start: " + String.valueOf(System.currentTimeMillis() - startTime));
        UserModel userModel= new UserModel(null, userReturnInfoModel.getName(),null,
                userReturnInfoModel.getEmail(), userReturnInfoModel.getId(),loginType);
        if(StringUtils.isEmpty(userModel.getNickname())){
            userModel.setNickname(userReturnInfoModel.getEmail());
        }

        UserModel userModelDao =userDao.selectCheckPW(null,null, userReturnInfoModel.getId(), loginType);
        logger.debug("trdPtyLogin_log 2 - first DB end: " + String.valueOf(System.currentTimeMillis() - startTime));
        if(userModelDao != null){
            userModel.setPin(userModelDao.getPin());
            userModel.setLogin_email(userReturnInfoModel.getEmail());
            userModel.setReturn_info(userReturnInfoModel);
            logger.debug("trdPtyLogin_log 3 - old user second DB start: " + String.valueOf(System.currentTimeMillis() - startTime));
            userDao.updateUser(userModel);
            logger.debug("trdPtyLogin_log 4 - old user second DB end: " + String.valueOf(System.currentTimeMillis() - startTime));
            userModel = userDao.selectByPIN(userModelDao.getPin());
            logger.debug("trdPtyLogin_log 4 - old user thrid DB end: " + String.valueOf(System.currentTimeMillis() - startTime));
            Token token = UserToken.generateToken(uuid, userModelDao.getPin());
            User user = new User(uuid,token.getValue(),userModel);
            user.setInvite_code(UserInviteCode.convertToInviteCode(userModelDao.getUser_id()));
            user.setRoute(getPinRoute(userModelDao.getPin()));
            user.setTokenTtl(UserToken.tokenTtl(userModelDao.getPin()));
            baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, user);
        }else{
            String pin = PINworker.getPIN();
            //新用户
            logger.debug("trdPtyLogin_log 2 - new user download icon start: " + String.valueOf(System.currentTimeMillis() - startTime));
            String iconUrl = userReturnInfoModel.getAvatar();
            if(StringUtils.isNotEmpty(iconUrl)){
                BaseResponse<ImgUpS3Response> response = DownloadFileUtil.downloadToAws(URLDecoder.decode(iconUrl,DesUtil.CHAR_ENCODE));
                if(response.isSuccess()){
                    userModel.setIcon(response.getResult().getImageLink());
                }else if(response.getError_code() == ErrorCode.USERSTATUS_ICON_DOWNLOAD_FAIL.getCode()){
                    userModel.setIcon(response.getResult().getImageLink());
                }else{
                    //就算头像设置不成功，依然登录成功
                    logger.error("userIconError:"+response.getError_msg()+",pin:"+pin);
                }
            }
            logger.debug("trdPtyLogin_log 2 - new user download icon end: " + String.valueOf(System.currentTimeMillis() - startTime));
            userModel.setPin(pin);
            userModel.setReturn_info(userReturnInfoModel);
            userModel.setSource(source);
            logger.debug("trdPtyLogin_log 3 - new user second DB start: " + String.valueOf(System.currentTimeMillis() - startTime));
            userDao.addUser(userModel);
            logger.debug("trdPtyLogin_log 3 - new user second DB end: " + String.valueOf(System.currentTimeMillis() - startTime));

            // 这个方法和注册方法取消事物就是因为promotionAppService.systemBindCoupon会根据pin去查询用户信息，所以必须得把用户信息先保存到数据库
            //发送首单优惠码
            try {
                BaseResponse<Integer> response = promotionAppService.systemBindCoupon(pin, null, GrantCouponEvent.REGISTER, null);
                if (!response.isSuccess()) {
                    logger.error("bindCouponError:" + pin + "," + response.getError_msg());
                }
            }catch (Exception e){
                e.printStackTrace();
            }

            userModel = userDao.selectByPIN(pin);
            logger.debug("trdPtyLogin_log 4 - new user third DB end: " + String.valueOf(System.currentTimeMillis() - startTime));
            Token token = UserToken.generateToken(uuid, pin);
            User user =new User(uuid,token.getValue(),userModel);
            user.setInvite_code(UserInviteCode.convertToInviteCode(userModel.getUser_id()));
            user.setRoute(getPinRoute(pin));
            user.setTokenTtl(UserToken.tokenTtl(pin));
            baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, user);
        }
        baseResponse.setLatency(System.currentTimeMillis() - startTime);
        return baseResponse;
    }

    /**
     * 退出登录
     *
     * @param pin
     * @param token
     * @return
     *
     * 退出登录
     */
    @Override
    public BaseResponse<Boolean> signOut(String pin, String token) {
        BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>(ErrorCode.OK);
        // 不会  删除缓存中的 pin  对应 token
        baseResponse.setResult(true);
        return baseResponse;
    }

    /**
     * 获取用户信息
     *
     * @param pin
     * @return
     */
    @Override
    public BaseResponse<User> getUserDetailInfo(String pin) {
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(pin) ){
            BaseResponse<User> baseResponse= new BaseResponse<User>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<User> baseResponse= new BaseResponse<User>();
        UserModel userModel;
        try {
            userModel=userDao.selectByPIN(pin);
            if(userModel == null){
                baseResponse.packData(false, ErrorCode.NOT_EXIST.getCode(),ErrorCode.NOT_EXIST.getError_msg(), null, null);
            }else {
                User user =new User(null,null,userModel);
                user.setInvite_code(UserInviteCode.convertToInviteCode(userModel.getUser_id()));
                user.setRoute(getPinRoute(pin));
                user.setTokenTtl(UserToken.tokenTtl(pin));
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, user);
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    /**
     * 获取用户信息
     *
     * @param pin
     * @return
     */
    @Override
    public BaseResponse<UserAttr> getUserAttr(String pin) {
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(pin) ){
            BaseResponse<UserAttr> baseResponse= new BaseResponse<UserAttr>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<UserAttr> baseResponse= new BaseResponse<UserAttr>();
        UserModel userModel;
        try {
            userModel=userDao.selectByPIN(pin);
            if(userModel == null){
                baseResponse.packData(false, ErrorCode.NOT_EXIST.getCode(),ErrorCode.NOT_EXIST.getError_msg(), null, null);
            }else {
                UserAttr userAttr =new UserAttr(userModel);
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, userAttr);
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    /**
     * 修改用户信息
     *
     * @param userModel
     * @return
     */
    @Override
    public BaseResponse<Boolean> modifyUserInfo(UserModel userModel) {
        long startTime = System.currentTimeMillis();
        if(userModel == null || userModel.getPwd() != null){
            BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>();
        try {
            int i=userDao.updateUser(userModel);
            if(i==1){
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, true);
            }else{
                baseResponse.packData(false, ErrorCode.PROCESS_ERROR.getCode(), "", null, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    /**
     * 修改密码
     *
     * @param userModel
     * @param oldPwd
     * @return
     */
    @Override
    public BaseResponse<Boolean> modifyUserPWD(UserModel userModel, String oldPwd) {
        long startTime = System.currentTimeMillis();
        if(userModel == null || StringUtils.isEmpty(oldPwd)
                ||StringUtils.isEmpty(userModel.getPin()) || StringUtils.isEmpty(userModel.getPwd())){
            BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>();
        try {
            //验证老密码是否正确
            UserModel userModelOld=userDao.selectCheckPW(null,userModel.getPin(),oldPwd,UserConfig.DEFAULT_LoginType);
            if(userModelOld == null){
                baseResponse.packData(false, ErrorCode.USERSTATUS_MODIFYINFO_INCORRECTPWD.getCode(),
                        ErrorCode.USERSTATUS_MODIFYINFO_INCORRECTPWD.getError_msg(), null, null);
                return baseResponse;
            }
            int i=userDao.updateUser(userModel);
            if(i==1){
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, true);
                //密码修改删除token
                redisCache.delKey(TokenConfig.TokenCacheKeyPrefix.concat(userModel.getPin()));
            }else{
                baseResponse.packData(false, ErrorCode.PROCESS_ERROR.getCode(), "", null, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    /**
     * 找回密码
     *
     * @param email     邮箱
     * @return
     */
    @Override
    public BaseResponse<User> forgotPWD(String email) {
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(email) || !EmailUtil.isEmail(email)){
            BaseResponse<User> baseResponse= new BaseResponse<User>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<User> baseResponse= new BaseResponse<User>();
        UserModel userModel;
        try {
            userModel=userDao.selectByEmail(email, UserConfig.DEFAULT_LoginType);
            if(userModel == null){
                baseResponse.packData(false, ErrorCode.USERSTATUS_FORGETPWD_EMIAL_NOT_REGISTERED.getCode(),ErrorCode.USERSTATUS_FORGETPWD_EMIAL_NOT_REGISTERED.getError_msg(), null, null);
            }else{
                String encode = DesUtil.encrypt(email + "##" + userModel.getPin()+"##"+startTime);
                String sig = UserToken.createToken(encode);
                encode = URLEncoder.encode(URLEncoder.encode(encode, DesUtil.CHAR_ENCODE),DesUtil.CHAR_ENCODE);
                String forgetPasswdUrl = UserConfig.userForgetPWDUrlPrefix + "?tp=" + encode + "&sig=" + sig;
                ForgetPWDEamilRequest forgetPWDEamilRequest = new ForgetPWDEamilRequest(userModel.getLogin_email(),
                        UserConfig.userForgetPWDEmailFrom, UserConfig.userForgetPWDEmailSubject,
                        UserConfig.userForgetPWDTitle, forgetPasswdUrl,userModel.getNickname(),userModel.getPin());
                generalServiceApi.sendEmailForgetPWD(forgetPWDEamilRequest);

                //redis
                redisCache.setToCache(ForogetPWDCacheKeyPrefix.concat(email).getBytes(),
                        UserConfig.UserForget_VALID_TIME, String.valueOf(startTime).getBytes());
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, null);
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    /**
     * 忘记密码修改密码
     * @param pw 新密码
     * @param tp 邮件中url的参数
     * @param sig 邮件中url的参数
     * @return
     */
    @Override
    public BaseResponse<Boolean> modifyFgtPwd(String pw,String tp,String sig){
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(pw) ||StringUtils.isEmpty(tp)
                || StringUtils.isEmpty(sig)){
            BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<Boolean> baseResponse= new BaseResponse<Boolean>();
        try {
            tp = URLDecoder.decode(tp, DesUtil.CHAR_ENCODE);
            String token = UserToken.createToken(tp);
            if(!sig.equals(token)){
                //用户修改自带的请求参数
                baseResponse.packData(false, ErrorCode.USERSTATUS_FORGETPWD_SIG_INVALID.getCode(),
                        ErrorCode.USERSTATUS_FORGETPWD_SIG_INVALID.getError_msg(), null, null);
                return baseResponse;
            }

            String decrypt = DesUtil.decrypt(tp);
            String[] ts = decrypt.split("##");
/*
            //map 存
            if(!ForgetPwdEmailBean.FORGET_PWD_USER.containsKey(ts[0])){
                // 忘记密码修改请求链接失效了
                baseResponse.packData(false, ErrorCode.PARAM_ERROR.getCode(), ErrorCode.PARAM_ERROR.getError_msg(), null, null);
                return baseResponse;
            }
            long sendTime = ForgetPwdEmailBean.FORGET_PWD_USER.get(ts[0]);
            if(startTime - sendTime > ForgetPwdEmailBean.ACTIVE_TIME){
                // 30分钟有效
                ForgetPwdEmailBean.FORGET_PWD_USER.remove(ts[0]);
                baseResponse.packData(false, ErrorCode.PARAM_ERROR.getCode(), ErrorCode.PARAM_ERROR.getError_msg(), null, null);
                return baseResponse;
            }
*/
            //redis
            byte[] redisValue  = redisCache.getFromCache(ForogetPWDCacheKeyPrefix.concat(ts[0]).getBytes());
            if(redisValue==null){
                baseResponse.packData(false, ErrorCode.USERSTATUS_FORGETPWD_EXPIRE.getCode(),
                        ErrorCode.USERSTATUS_FORGETPWD_EXPIRE.getError_msg(), null, null);
                return baseResponse;
            }else if(startTime - Long.valueOf(new String(redisValue)) * 1000 > UserConfig.UserForget_VALID_TIME * 1000  ){
                baseResponse.packData(false, ErrorCode.USERSTATUS_FORGETPWD_EXPIRE.getCode(),
                        ErrorCode.USERSTATUS_FORGETPWD_EXPIRE.getError_msg(), null, null);
                return baseResponse;
            }else if(!new String(redisValue).equals(ts[2])){
                baseResponse.packData(false, ErrorCode.USERSTATUS_FORGETPWD_INVALID.getCode(),
                        ErrorCode.USERSTATUS_FORGETPWD_INVALID.getError_msg(), null, null);
                return baseResponse;
            }else {
                logger.info("忘记密码：redis-->"+ new String(redisValue));
                redisCache.delKey(ForogetPWDCacheKeyPrefix.concat(ts[0]));
            }

            UserModel userModel = new UserModel();
            userModel.setPin(ts[1]);
            userModel.setPwd(pw);
            int i = userDao.updateUser(userModel);
            if(i==1){
                baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, true);
                ForgetPwdEmailBean.FORGET_PWD_USER.remove(ts[0]);
                //密码修改删除token
                redisCache.delKey(TokenConfig.TokenCacheKeyPrefix.concat(ts[1]));
            }else{
                baseResponse.packData(false, ErrorCode.PROCESS_ERROR.getCode(), "", null, false);
            }
        }catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.BASE_SERVICE_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }


    @Override
    public BaseResponse<String> bindInviteCode(String pin,String inviteCode){
        if(StringUtils.isEmpty(pin) ||StringUtils.isEmpty(inviteCode)){
            BaseResponse<String> baseResponse= new BaseResponse<String>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<String> response = new BaseResponse<String>();
        long startTime = System.currentTimeMillis();
        int userId = 0;
            // 判断邀请码是否有效
        try {
            userId = UserInviteCode.convertToUserId(inviteCode);
        } catch (Exception e){
            response.packData(false,ErrorCode.INVITE_CODE_INCORRECT.getCode(),ErrorCode.INVITE_CODE_INCORRECT.getError_msg(),null,null);
            return response;
        }
        try {
            UserModel um = userDao.selectByUserId(userId);
            if(um == null){
                response.packData(false,ErrorCode.INVITE_USER_INCORRECT.getCode(),ErrorCode.INVITE_USER_INCORRECT.getError_msg(),null,null);
                return response;
            }

            UserModel userModel = userDao.selectByPIN(pin);
            // 判断当前绑定用户是否满足邀请条件
            if(userModel == null || userModel.getIsHistoricalUser() == 1
                    || StringUtils.isNotEmpty(userModel.getInvite_pin())
                    || inviteCode.equals(UserInviteCode.convertToInviteCode(userModel.getUser_id()))){
                response.packData(false,ErrorCode.INVITE_USER_INCORRECT.getCode(),ErrorCode.INVITE_USER_INCORRECT.getError_msg(),null,null);
                return response;
            }
            UserModel update = new UserModel();
            update.setPin(pin);
            update.setInvite_pin(um.getPin());
            userDao.updateUser(update);

            response.packData(true,ErrorCode.OK.getCode(),ErrorCode.OK.getError_msg(),null,um.getPin());
        }catch (Exception e){
            e.printStackTrace();
            response.packData(false, ErrorCode.BASE_SERVICE_ERROR.getCode(), e.getMessage(), null, null);
        }
        response.setLatency(System.currentTimeMillis()-startTime);
        return response;
    }

    /**
     * 返回第三方登录绑定的邮箱
     *
     * @param thirdID
     * @param loginType
     * @return
     */
    @Override
    public BaseResponse<String> getThirdLoginEmail(String thirdID, int loginType) {
        long startTime = System.currentTimeMillis();
        if(StringUtils.isEmpty(thirdID) || loginType==0){
            BaseResponse<String> baseResponse= new BaseResponse<String>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<String> baseResponse= new BaseResponse<String>();
        try {
            String email = userDao.selectEmailByThirdLoginID(thirdID,loginType);
            baseResponse.packData(true, ErrorCode.OK.getCode(), "", null, email);
        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis()-startTime);
        return baseResponse;
    }

    @Override
    public BaseResponse<String> getInviteCode(String pin){
        if(StringUtils.isEmpty(pin)){
            BaseResponse<String> baseResponse= new BaseResponse<String>(ErrorCode.PARAM_ERROR);
            return baseResponse;
        }
        BaseResponse<String> response = new BaseResponse<String>();
        long startTime = System.currentTimeMillis();
        try {
            UserModel userModel = userDao.selectByPIN(pin);
            // 判断当前绑定用户是否满足邀请条件
            if(userModel == null){
                response.packData(false,ErrorCode.NOT_EXIST.getCode(),ErrorCode.NOT_EXIST.getError_msg(),null,null);
                return response;
            }
            String inviteCode = UserInviteCode.convertToInviteCode(userModel.getUser_id());
            response.packData(true,ErrorCode.OK.getCode(),ErrorCode.OK.getError_msg(),null,inviteCode);
        }catch (Exception e){
            e.printStackTrace();
            response.packData(false, ErrorCode.BASE_SERVICE_ERROR.getCode(), e.getMessage(), null, null);
        }
        response.setLatency(System.currentTimeMillis()-startTime);
        return response;
    }

    @Override
    public BaseListResponse getUserByEmailOrInviteCode(String emailOrCode) {
        long start = System.currentTimeMillis();
        BaseListResponse baseResponse = new BaseListResponse(ErrorCode.PARAM_ERROR);
        if(StringUtils.isEmpty(emailOrCode)){
            return baseResponse;
        }
        String email = null;
        Integer userId = null;
        if(EmailUtil.isEmail(emailOrCode)){
            email = emailOrCode;
        }else{
            try {
                userId = UserInviteCode.convertToUserId(emailOrCode);
            } catch (Exception e){
                return baseResponse;
            }
        }
        if(email == null && userId == null){
            return baseResponse;
        }
        try{
            UserModel model = new UserModel();
            model.setLogin_email(email);
//            model.setUser_id(userId);
            List<UserModel> userModels = userDao.selectByEmailOrId(model);
            List<User> result = new ArrayList<User>();
            if(userModels != null && userModels.size() > 0){
                for(UserModel m : userModels){
                    User u = new User();
                    u.setLogin_email(m.getLogin_email());
                    u.setNickname(m.getNickname());
                    u.setLogin_type(m.getLogin_type());
                    u.setPin(m.getPin());
                    u.setStatus_code(m.getStatus_code());
                    u.setIsHistoricalUser(m.getIsHistoricalUser());
                    u.setUser_type(m.getUser_type());
                    u.setUser_level(m.getUser_level());
                    u.setInvite_code(UserInviteCode.convertToInviteCode(m.getUser_id()));
                    u.setRoute(getPinRoute(m.getPin()));
                    u.setNetred(m.getNetred());
                    result.add(u);
                }
                ListModel list = new ListModel();
                list.setList(result);
                list.setAmount(result.size());
                baseResponse.packData(true, ErrorCode.OK.getCode(), ErrorCode.OK.getError_msg(), null, list);
            }
        }catch (Exception e){
            e.printStackTrace();
            baseResponse.packData(false, ErrorCode.DB_ERROR.getCode(), e.getMessage(), null, null);
        }
        baseResponse.setLatency(System.currentTimeMillis() - start);

        return baseResponse;
    }

    private int getPinRoute(String pin){
        Integer d = UserConfig.ROUTE_MAP.get(pin);
        if(d != null){
            return d;
        }
        int hash = UserToken.hashingAsInt(pin);
        int mode = Math.abs(hash % 100);
        int result = 1;
        for(;result < UserConfig.ROUTE_TYPE.length;result++){
            if(mode >=  UserConfig.ROUTE_TYPE[result - 1] && mode <  UserConfig.ROUTE_TYPE[result]){
                return result;
            }
        }
        return result;
    }

}
